#include <stdio.h>
#include <stdlib.h>
#include "sll.h"

static link head = NULL;

link new_node(item_t item)
{
    link p = malloc(sizeof *p);
    p->item = item;
    p->next = NULL;
    return p;
}

static void free_node(link p, destructor dtor)
{
    if (dtor != NULL)
        dtor(p);
    free(p);
}

link search(item_t key)
{
    link p;
    for (p = head; p; p = p->next)
        if (p->item == key)
            return p;
    return NULL;
}

void insert(link p)
{
    p->next = head;
    head = p;
}

void delete(link p, destructor dtor)
{
    link *pnext;
    for (pnext = &head; *pnext; pnext = &(*pnext)->next)
        if (*pnext == p) {
            *pnext = p->next;
            break;
        }
    free_node(p, dtor);
    return;
}

void traverse(void (*visit)(link))
{
    link p;
    for (p = head; p; p = p->next)
        visit(p);
}

static unsigned int n = 0;
static void cnt_add(void)
{
    n += 1;
}

static void cnt_reset(void)
{
    n = 0;
}

static unsigned int cnt_read(void)
{
    return n;
}

static void cnt(link p)
{
    cnt_add();
}

unsigned int count(void)
{
    cnt_reset();
    traverse(cnt);
    return cnt_read();
}

void reverse(void)
{
    unsigned int n = count();
    printf("----n=%d--%s----\n", n, __FUNCTION__);
    if (n < 2) {
        fprintf(stderr, "few data in the list. nothing reverse.\n");
        return;
    }
    
    link pre, forward;
    pre = head;
    head = head->next;
    pre->next = NULL;
    forward = head->next;
    head->next = pre;
    
    for (; forward;) {
        pre = head;
        head = forward;
        forward = forward->next;
        head->next = pre;            
    }
}


void destroy(destructor dtor)
{
    link q, p = head;
    head = NULL;
    while (p) {
        q = p;
        p = p->next;
        free_node(q, dtor);
    }
}

void push(link p)
{
    insert(p);
}

link pop(void)
{
    if (head == NULL)
        return NULL;
    else {
        link p = head;
        head = head->next;
        return p;
    }
}


